/*
	File : ShowFindUpdateAGV.cpp
	Author : Achmad Giovani
*/

#include "ShowFindUpdateAGV.h"

using namespace std;

/* public methods */

string ShowFindUpdateAGV::show(vector<Product> products){
	/*	function : show()
		author : Achmad Giovani
		-> list all products sorted by price [print name, ID and price] <-
	*/
	stringstream ss; /* string stream to store output */
	
	/* sort products by price, ascending */
	sort(products.begin(), products.end(), compareProduct);
	
	/* store to string stream */
	for (int i=0; i<products.size(); ++i){
		ss << products.at(i).get_prod_name() 
			<< " | ID = " << products.at(i).get_prod_id()
			<< " | price = " << products.at(i).get_prod_price() << endl;
	}
	ss << endl;
	/* convert to string */
	string out=ss.str();
	
	/* string output */
	return out;
	
}

double ShowFindUpdateAGV::find(vector<Cart_item> cart_items, vector<Category> cats, vector<Product> prods, string cat_name){
	/*	function : find()
		author : Achmad Giovani
		-> Calculate total sales for a given category <-
	*/
	
	/* find appropriate category ID based on category name */
	int cat_id;
	for (int i=0; i < cats.size(); ++i){
		if (cats.at(i).get_cat_name() == cat_name){ /* if equals */
			cat_id = cats.at(i).get_cat_id();
			break;
		}
		else cat_id = 0;
	}
	
	/* find appropriate Product IDs which are the members of the Category */
	/* store appropriate Product IDs into a vector */
	vector<int> prod_ids;
	for (int i=0; i < prods.size(); ++i){
		if (prods.at(i).get_cat_id() == cat_id){
			prod_ids.push_back(prods.at(i).get_prod_id());
		}
	}
	
	//DEBUG
	/* 
	for (int i=0; i < prod_ids.size(); ++i){
		cout << "prod id = " << prod_ids.at(i) << endl;
	}
	*/
	
	/* now count the subtotal sales from Cart_items records */
	double sum_sales = 0;	/* variable for storing the total sales */
	
	for (int i=0; i < cart_items.size(); ++i){
		/* find records in each Cart_items that have same Product IDs stored in the vector */
		for (int j=0; j < prod_ids.size(); ++j){
			if (cart_items.at(i).get_prod_id() == prod_ids.at(j)){
				/* count subtotal per Cart_item => Product price * Product quantity */
				double subtotal = get_prod_price_byID(prods, cart_items.at(i).get_prod_id()) * cart_items.at(i).get_prod_qty();
				/* increment sum_sales values by subtotals */
				sum_sales += subtotal;
			}
		}
	}
	
	return sum_sales; /* return total sales */	
}

void ShowFindUpdateAGV::update(Cart_item ci, vector<Cart> carts, vector<Product> prods, vector<Cart_item> &cart_items){
	/*	function : update()
		author : Achmad Giovani
		-> Add a new cart item to an existing cart <-
	*/
	
	bool found = false;
	bool cart_item_exists = false;
	bool product_exists = false;
	
	/* check if cart exists */
	for (int i=0; i < carts.size(); ++i){
		if (carts.at(i).get_cart_id() == ci.get_cart_id()){ /* if equals */
			found = true;
			break;
		}
	}
	
	/* check if cart_item exists */
	for (int i=0; i < cart_items.size(); ++i){
		if (cart_items.at(i).get_cart_item_id() == ci.get_cart_item_id()){ /* if equals */
			cart_item_exists = true;
			break;
		}
	}
	
	/* check if product exists */
	for (int i=0; i < prods.size(); ++i){
		if (prods.at(i).get_prod_id() == ci.get_prod_id()){ /* if equals */
			product_exists = true;
			break;
		}
	}
	
		
	if (found && !cart_item_exists && product_exists){
		//add the new cart item
		cart_items.push_back(ci);		
	}
	else if (!found){
		cout << "Cart doesn't exits" << endl;
	}
	else if (cart_item_exists){
		cout << "Cart item already exists " << endl;
	}
	else if (!product_exists){
		cout << "Product doesn't exists " << endl;
	}

}

/* private methods */

bool ShowFindUpdateAGV::compareProduct(Product p1, Product p2){
	return (p1.get_prod_price() < p2.get_prod_price());
}

double ShowFindUpdateAGV::get_prod_price_byID(vector<Product> prods, int id){ 	/* AGV on S3 */
	double out = 0;
	for (int i=0; i < prods.size(); ++i){
		if(prods.at(i).get_prod_id() == id){
			out = prods.at(i).get_prod_price();
			break;
		}
	}
	return out;
}